from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from .elements import e
from .globals import g
from .log import logger


# def locating_element(element_name, action=''):
def locating_element(element_id, action='', wait_time=None):
    el_location = None
    # el_info = e.get(element_name)
    el_info = e.get(element_id)
    if not el_info:
        logger.error(f'元素[{element_id}]没有定义！')
        raise Exception(f'元素[{element_id}]没有定义！')
    else:
        el, value = el_info
        element_by = el['by'].upper()
        element_id = el['element_id']
        element_name = el['element']

    try:
        value = value.format(**g.var)
    except KeyError as kexception:
        logger.error(f'缺少参数：{str(kexception)[1:-1]}')
        raise
    except Exception as exception:
        logger.exception(str(exception))
        raise

    # logger.debug(f'location by: {el["by"]}, value: {value}')
    try:
        wait_time = wait_time if wait_time else g.element_wait_timeout
        wait = WebDriverWait(g.driver, wait_time)
        g.driver.implicitly_wait(wait_time)
        if action == 'not_visible':
            el_location = wait.until(EC.invisibility_of_element_located((getattr(By, element_by), value)))

        try:
            if g.driver.name in ('chrome', 'safari'):
                g.driver.execute_script(
                    "arguments[0].scrollIntoViewIfNeeded(true)", el_location)
            else:
                g.driver.execute_script(
                    "arguments[0].scrollIntoView(false)", el_location)
        except:
            pass

        if action == 'CLICK':
            el_location = wait.until(EC.element_to_be_clickable((getattr(By, element_by), value)))
        elif not el_location:
            el_location = wait.until(EC.visibility_of_element_located((getattr(By, element_by), value)))

    except TimeoutException:
        try:
            wait = WebDriverWait(g.driver, 0.1)
            el_location = wait.until(EC.presence_of_element_located((getattr(By, element_by), value)))
        except:
            g.driver.implicitly_wait(g.element_wait_timeout)
            logger.error(f'元素<{element_name}>定位 {wait_time}s 超时，id: {element_id}, '
                         f'by: {element_by.lower()}, value: {value}')
            raise
    finally:
        g.driver.implicitly_wait(g.element_wait_timeout)

    g.driver.implicitly_wait(g.element_wait_timeout)
    return el_location


def locating_elements(elements):
    elements_location = {}
    for el in elements:
        elements_location[el] = locating_element(el)
    return elements_location


def locating_data(keys):
    data_location = {}
    for key in keys:
        data_location[key] = locating_element(key)
    return data_location
